home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AppsToGo / DTS.Draw / TRRectObj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  8.3 KB  |  310 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        TRRectObj.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1992-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19. /* See the files "=How to write your app" and "=Using TreeObj.c" for information
  20. ** on this function. */
  21.  
  22. /* This file implements the messages for the round-rect object.  Many of the messages
  23. ** can be handled by the rect object, as they deal with a rect structure.  Only
  24. ** a few of them are round-rect-specific. */
  25.  
  26. /* It would seem that you would want a custom hit-test message handler here, but
  27. ** the rect object first checks to see if the hit is within the bounding box of
  28. ** the object, and if so, it then calls the object to return the region.  This
  29. ** allows the rect object to generically handle hit-testing. */
  30.  
  31.  
  32.  
  33. /*****************************************************************************/
  34.  
  35.  
  36.  
  37. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  38. #include "App.protos.h"        /* Get the prototypes for the application.        */
  39.  
  40. #ifndef __OSEVENTS__
  41. #include <OSEvents.h>
  42. #endif
  43.  
  44. #ifndef __OSUTILS__
  45. #include <OSUtils.h>
  46. #endif
  47.  
  48. #ifndef __QUICKDRAW__
  49. #include <Quickdraw.h>
  50. #endif
  51.  
  52. #ifndef __TREEOBJ2__
  53. #include "TreeObj2.h"
  54. #endif
  55.  
  56. #ifndef __UTILITIES__
  57. #include "Utilities.h"
  58. #endif
  59.  
  60.  
  61.  
  62. /*****************************************************************************/
  63.  
  64.  
  65.  
  66. static RRectObjPeek    *gMWERKSDebug;
  67.     /* For Metroweks debugging of AppsToGo "objects", you need an instance of the
  68.     ** same type you wish to view it in the debugger.  Now we have an instance. */
  69.  
  70.  
  71.  
  72. /*****************************************************************************/
  73. /*****************************************************************************/
  74.  
  75. #ifdef applec
  76. #pragma segment DTSDrawSeg2
  77. #endif
  78.  
  79. /*****************************************************************************/
  80. /*****************************************************************************/
  81.  
  82.  
  83.  
  84. long    TRRectObj(TreeObjHndl hndl, short message, long data)
  85. {
  86.     Rect        rct, grabber, *rptr;
  87.     RgnHandle    rgn, accumRgn;
  88.     short        w, h, oldh, oldw;
  89.     ClickInfo    *click;
  90.     TreeObjHndl    hhndl;
  91.     Point        where, pt, curMouse;
  92.     EventRecord    option;
  93.     RGBColor    rgb, rgb2;
  94. #if VH_VERSION
  95.     char        *cptr;
  96. #endif
  97.  
  98.     switch (message) {
  99.         case INITMESSAGE:
  100.             TRectObj(hndl, message, data);
  101.             mDerefRRect(hndl)->width = mDerefRRect(hndl)->height = 20;
  102.             break;
  103.  
  104.         case FREEMESSAGE:
  105.         case COPYMESSAGE:
  106.         case UNDOMESSAGE:
  107.         case CONVERTMESSAGE:
  108.         case FREADMESSAGE:
  109.         case FWRITEMESSAGE:
  110.         case HREADMESSAGE:
  111.         case HWRITEMESSAGE:
  112.         case GETOBJRECTMESSAGE:
  113.         case SETOBJRECTMESSAGE:
  114.         case SECTOBJRECTMESSAGE:
  115.         case CLICKMESSAGE:
  116.         case KEYMESSAGE:
  117.         case SETSELECTMESSAGE:
  118.         case GETSELECTMESSAGE:
  119.         case COMPAREMESSAGE:
  120.             return(TRectObj(hndl, message, data));
  121.             break;
  122.  
  123.         case GETBBOXMESSAGE:
  124.             TRectObj(hndl, message, data);
  125.             if (mDerefCommon(hndl)->selected) {
  126.                 rct = mDerefRRect(hndl)->rect;
  127.                 w   = mDerefRRect(hndl)->width;
  128.                 h   = mDerefRRect(hndl)->height;
  129.                 grabber.top  = rct.top  + (h / 2);
  130.                 grabber.left = rct.left + (w / 2);
  131.                 grabber.bottom = (grabber.top  -= 3) + 6;
  132.                 grabber.right  = (grabber.left -= 3) + 6;
  133.                 rptr = (Rect *)data;
  134.                 if (rptr->right < grabber.right)
  135.                     rptr->right = grabber.right;
  136.                 if (rptr->bottom < grabber.bottom)
  137.                     rptr->bottom = grabber.bottom;
  138.             }
  139.             break;
  140.  
  141.         case HITTESTMESSAGE:
  142.             click = (ClickInfo *)data;
  143.             hhndl = (TreeObjHndl)TRectObj(hndl, message, data);
  144.                 /* We must call TRectObj::HITTESTMESSAGE to set some static
  145.                 ** variables that TRectObj::SELECTOBJMESSAGE uses. */
  146.             if ((!hhndl) && (click->message == HITTESTGRABBER)) {
  147.                 if (mDerefRoot(GetRootHndl(hndl))->numSelected == 1) {
  148.                     if (mDerefRRect(hndl)->selected) {
  149.                         rct   = mDerefRRect(hndl)->rect;
  150.                         where = click->localEvent.where;
  151.                         GetMouse(&curMouse);
  152.                         grabber.top  = pt.v = (rct.top  + (mDerefRRect(hndl)->height / 2));
  153.                         grabber.left = pt.h = (rct.left + (mDerefRRect(hndl)->width / 2));
  154.                         grabber.bottom = (grabber.top  -= 3) + 6;
  155.                         grabber.right  = (grabber.left -= 3) + 6;
  156.                         if (PtInRect(where, &grabber)) {
  157.                             click->localEvent.where = pt;
  158.                             click->offset.h         = pt.h - curMouse.h;
  159.                             click->offset.v         = pt.v - curMouse.v;
  160.                             click->oldFlip          = 0;
  161.                             click->newFlip          = 0;
  162.                             click->grabber          = 7;
  163.                             hhndl = hndl;
  164.                         }
  165.                     }
  166.                 }
  167.             }
  168.             return((long)hhndl);
  169.             break;
  170.  
  171.         case GETRGNMESSAGE:
  172.             rgn      = NewRgn();
  173.             accumRgn = (RgnHandle)data;
  174.             if (accumRgn)
  175.                 if (GetHandleSize((Handle)accumRgn) > 10000)
  176.                     return((long)rgn);
  177.             OpenRgn();
  178.             rct = mDerefRRect(hndl)->rect;
  179.             FrameRoundRect(&rct, mDerefRRect(hndl)->width, mDerefRRect(hndl)->height);
  180.             CloseRgn(rgn);
  181.             if (accumRgn)
  182.                 UnionRgn(rgn, accumRgn, accumRgn);
  183.             return((long)rgn);
  184.             break;
  185.  
  186.         case DRAWMESSAGE:
  187.             rct = mDerefRRect(hndl)->rect;
  188.             h   = mDerefCommon(hndl)->penHeight;
  189.             w   = mDerefCommon(hndl)->penWidth;
  190.             PenSize(w, h);
  191.             w = mDerefRRect(hndl)->width;
  192.             h = mDerefRRect(hndl)->height;
  193.             switch (data) {
  194.                 case DRAWOBJ:
  195.                     if (gQDVersion)
  196.                         GetForeColor(&rgb);
  197.                     ForeColor(whiteColor);
  198.                     if (gQDVersion) {
  199.                         rgb2 = mDerefRRect(hndl)->contentColor;
  200.                         RGBForeColor(&rgb2);
  201.                     }
  202.                     PaintRoundRect(&rct, w, h);
  203.                     ForeColor(blackColor);
  204.                     if (gQDVersion) {
  205.                         rgb2 = mDerefRRect(hndl)->borderColor;
  206.                         RGBForeColor(&rgb2);
  207.                     }
  208.                     FrameRoundRect(&rct, w, h);
  209.                     if (gQDVersion)
  210.                         RGBForeColor(&rgb);
  211.                     break;
  212.                 case ERASEOBJ:
  213.                     EraseRoundRect(&rct, w, h);
  214.                     break;
  215.                 case DRAWSELECT:
  216.                     TRectObj(hndl, message, data);
  217.                     if (mDerefCommon(hndl)->selected) {
  218.                         grabber.top  = rct.top  + (h / 2);
  219.                         grabber.left = rct.left + (w / 2);
  220.                         grabber.bottom = (grabber.top  -= 3) + 6;
  221.                         grabber.right  = (grabber.left -= 3) + 6;
  222.                         InvertRect(&grabber);
  223.                     }
  224.                     break;
  225.                 case DRAWGHOST:
  226.                     PenMode(patXor);
  227.                     FrameRoundRect(&rct, w, h);
  228.                     break;
  229.                 case DRAWMASK:
  230.                     FillRoundRect(&rct, w, h, (ConstPatternParam)&qd.black);
  231.                     break;
  232.             }
  233.             PenNormal();
  234.             break;
  235.  
  236.         case PRINTMESSAGE:
  237.             TRRectObj(hndl, DRAWMESSAGE, DRAWOBJ);
  238.             break;
  239.  
  240. #if VH_VERSION
  241.         case VHMESSAGE:
  242.             cptr = ((VHFormatDataPtr)data)->data;
  243.             ccatchr(cptr, 13, 2);
  244.             ccat   (cptr, "$10: TRRectObj:");
  245.             ccatchr(cptr, 13, 1);
  246.             ccat   (cptr, "  $00: selected = ");
  247.             ccatdec(cptr, mDerefRRect(hndl)->selected);
  248.             ccatchr(cptr, 13, 1);
  249.             rct = mDerefRRect(hndl)->rect;
  250.             ccat      (cptr, "  $02: rect     = ($");
  251.             ccatpadhex(cptr, 0, 4, 4, rct.top);
  252.             ccat      (cptr, ",$");
  253.             ccatpadhex(cptr, 0, 4, 4, rct.left);
  254.             ccat      (cptr, ",$");
  255.             ccatpadhex(cptr, 0, 4, 4, rct.bottom);
  256.             ccat      (cptr, ",$");
  257.             ccatpadhex(cptr, 0, 4, 4, rct.right);
  258.             ccat      (cptr, ")");
  259.             ccatchr   (cptr, 13, 1);
  260.             ccat      (cptr, "  $0A: width    = ");
  261.             ccatdec   (cptr, mDerefRRect(hndl)->width);
  262.             ccatchr   (cptr, 13, 1);
  263.             ccat      (cptr, "  $0C: height   = ");
  264.             ccatdec   (cptr, mDerefRRect(hndl)->height);
  265.             return(true);
  266.             break;
  267. #endif
  268.  
  269.         case SIZEMESSAGE:
  270.             click = (ClickInfo *)data;
  271.             if (click->grabber != 7)
  272.                 return(TRectObj(hndl, message, data));
  273.  
  274.             DoTreeObjMethod(hndl, GETOBJRECTMESSAGE, (long)&rct);
  275.             oldw = mDerefRRect(hndl)->width;
  276.             oldh = mDerefRRect(hndl)->height;
  277.  
  278.             GetMouse(&curMouse);
  279.             curMouse.h += click->offset.h;
  280.             curMouse.v += click->offset.v;
  281.             w = (curMouse.h - rct.left) * 2;
  282.             h = (curMouse.v - rct.top) * 2;
  283.             if (w < 10) w = 10;
  284.             if (h < 10) h = 10;
  285.             if (w > (rct.right  - rct.left)) w = rct.right  - rct.left;
  286.             if (h > (rct.bottom - rct.top))  h = rct.bottom - rct.top;
  287.  
  288.             OSEventAvail(nullEvent, &option);
  289.             if (option.modifiers & shiftKey) {
  290.                 if (w > h) w = h;
  291.                 if (h > w) h = w;
  292.             }
  293.             if ((w != oldw) || (h != oldh)) {
  294.                 mDerefRRect(hndl)->width  = w;
  295.                 mDerefRRect(hndl)->height = h;
  296.                 return(true);
  297.             }
  298.             return(false);
  299.             break;
  300.  
  301.         default:
  302.             break;
  303.     }
  304.  
  305.     return(noErr);
  306. }
  307.  
  308.  
  309.  
  310.